// Copyright 2009 Google Inc. All Rights Reserved.
package com.google.wave.extensions.polly;

import java.util.logging.Logger;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Element;
import com.google.wave.api.ElementType;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.FormElement;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.SaveResult;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;

/**
 * Polly is a robot that acts as an interactive form builder to help Wave users
 * construct, distribute and collect polls.
 * 
 * @author scovitz@google.com (Seth Covitz)
 */
@SuppressWarnings("serial")
public class CaseyServlet extends AbstractRobotServlet {

	
	private static final Logger LOG = Logger.getLogger(CaseyServlet.class.getName());
	
  /**
   * The main event handler for Polly. It constructs an object that knows how
   * to operate on the different wavelet 'types' that Polly has created.
   * 
   * @param context the robot context while handling the events.
   */
	  @Override
	  public void processEvents(RobotMessageBundle context) {
		  Blip blip = context.getWavelet().getRootBlip();
		  String dataDoc = context.getWavelet().getDataDocument("force");

		  for (Event e: context.getEvents()) {
			  LOG.info("\nEvent: " + e.getType().toString());
			  if (e.getType().equals(EventType.WAVELET_SELF_ADDED)) {
				  if (dataDoc == null) {
					  dataDoc = "count:0";
					  FormElement btn = new FormElement(ElementType.BUTTON, "forcebtn", "Create Case");
					  context.getWavelet().getRootBlip().getDocument().appendElement(btn);
					  context.getWavelet().setDataDocument("force", dataDoc);
				  }
			  } else if (e.getType().equals(EventType.FORM_BUTTON_CLICKED)) {
				  String newCount = addOneToCount(dataDoc);
				  //blip.getDocument().append("\n" + e.getType().toString() + " " + e.getTimestamp().toString() + " [" + newCount + "]");
				  blip.getDocument().getFormView().delete(blip.getDocument().getFormView().getFormElement("forcebtn"));
				  dataDoc = "count:" + newCount;
				  context.getWavelet().setDataDocument("force", dataDoc);
				  String caseId = makeCase(context.getWavelet());
				  blip.getDocument().append("Wavelet is now a case: " + caseId.split(":")[0] + "\n");
				  blip.getDocument().appendMarkup("http://na6.salesforce.com/" + caseId.split(":")[1] + " Acess Case Here");
			  }
		  }
	  }
	  
	  private String makeCase(Wavelet wavelet) {
			SalesforceSessionMgr ssm = new SalesforceSessionMgr();
			ssm.setGlobalUsername(getServletContext().getInitParameter("salesforce.username"));
			ssm.setGlobalPassword(getServletContext().getInitParameter("salesforce.password"));
			
			String 	returnVal = "error";
			try {
				PartnerConnection conn = ssm.getGlobalConnection();
				SaveResult[] srs = conn.create(getCaseObject(wavelet));
				if (srs[0].getSuccess()) {
					String id = srs[0].getId();
					QueryResult cases = conn.query("Select Id, CaseNumber From Case Where Id = '" + id + "'");
					returnVal = (String) cases.getRecords()[0].getField("CaseNumber") + ":" + id;
					//returnVal = srs[0].getId();
				} else {
					returnVal = srs[0].getErrors()[0].getMessage();
				}
			} catch (ConnectionException e) {
				// TODO Auto-generated catch block
				StackTraceElement[] trace = e.getStackTrace();
				String stack = e.getMessage() + "";
			
				for (int i=0;i<trace.length;i++) {
			
					stack += trace[i].toString() + "\n";
				}
				LOG.warning("Error creating case: " + e.getMessage());
				e.printStackTrace();
			}
			return returnVal;
	  }
	  private SObject[] getCaseObject(Wavelet wavelet) {
		  SObject obj = new SObject();
		  obj.setType("case");
		  obj.setField("Subject", wavelet.getTitle());
		  obj.setField("WaveletId__c", wavelet.getWaveId());
		  obj.setField("Origin", "Wave");
		  obj.setField("Status", "New");
		  LOG.warning("Setting field 'type' to 'case'");
		  
		  return new SObject[] { obj };
	  }
	  private String addOneToCount(String dataDoc) {
		  return String.valueOf(Long.valueOf(getCount(dataDoc)) + 1);
	  }
	  private String getCount(String dataDoc) {
		  return dataDoc.split(":")[1];
	  }
  //@Override
  public void processEvents1(RobotMessageBundle context) {

	 
    // Poll Administration Flow
    /*if (isNewPollyWave(context) || AdminWavelet.isAdminWavelet(context)) {
      AdminWavelet adminWavelet = new AdminWavelet(context);
      adminWavelet.handleEvents();
      return;
    }*/

    for (Event e: context.getEvents()) {
    	if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {   
    		System.out.println("\n\n\nIn the WAVELET_PARTICIPANTS_CHANGED...\n\n\n");
    		LOG.warning("\n\n\nIn the WAVELET_PARTICIPANTS_CHANGED...\n\n\n");
    		Blip blip = context.getWavelet().appendBlip();
    		TextView textView = blip.getDocument();
    		blip.getWavelet().getWaveletId(); 
    		textView.append("Hi, everybody!");
    		
    		if (CaseWavelet.isCaseWavelet(context)) {
    		      CaseWavelet caseWavelet = new CaseWavelet(context);
    		      caseWavelet.create();
    		      //caseWavelet.handleEvents();
    		}
      	}
    	if (e.getType().equals(EventType.FORM_BUTTON_CLICKED)) {
    		Blip blip = context.getWavelet().appendBlip();
    		TextView textView = blip.getDocument();
    		LOG.warning("\n\n\nIn the FORM_BUTTON_CLICKED handler...\n\n\n");
    		CaseWavelet pollWavelet = new CaseWavelet(context);
    		textView.append("I'll be damned, you CLICKED me!");
    		pollWavelet.handleCaseCreation();
    	}
    	if (e.getType().equals(EventType.WAVELET_SELF_ADDED)) {
    		LOG.warning("In the Wavelet Self Added handler...");
    		CaseWavelet pollWavelet = new CaseWavelet(context);
    		pollWavelet.create();
    		pollWavelet.handleEvents();
    	}
    }

    // Poll Recipient Flow
    /*if (CaseWavelet.isCaseWavelet(context)) {
      CaseWavelet caseWavelet = new CaseWavelet(context);
      caseWavelet.handleEvents();
      return;
    }*/
  }
  
}
